﻿#pragma once

#include "MapObject.h"
#include "../../Shared/Enums.h"
#include "Effect.h"
#include "Frames.h"
#include "../../Shared/ServerPackets.h"
#include "../MirGraphics/MLibrary.h"
#include <string>
#include <unordered_map>
#include <vector>
#include <cmath>
#include <any>
#include <optional>
#include "../../stringhelper.h"

using namespace Client::MirGraphics;
using namespace Client::MirScenes;
using namespace Client::MirSounds;
namespace S = ServerPackets;
using namespace Client::MirControls;

namespace Client::MirObjects
{
    class MonsterObject : public MapObject
    {
    public:
        virtual ~MonsterObject()
        {
            delete Frames;
            delete Frame;
            delete TargetPoint;
            delete OldNameColor;
        }

        ObjectType getRace() const override;

        bool getBlocking() const override;

        Point *getManualLocationOffset() const;

        Monster BaseImage = static_cast<Monster>(0);
        unsigned char Effect = 0;
        bool Skeleton = false;

        FrameSet *Frames = new FrameSet();
        Frame *Frame;
        int FrameIndex = 0, FrameInterval = 0, EffectFrameIndex = 0, EffectFrameInterval = 0;

        unsigned int TargetID = 0;
        Point *TargetPoint;

        bool Stoned = false;
        unsigned char Stage = 0;
        int BaseSound = 0;

        long long ShockTime = 0;
        bool BindingShotCenter = false;

        Color *OldNameColor;

        SpellEffect CurrentEffect = static_cast<SpellEffect>(0);

        MonsterObject(unsigned int objectID);

        void Load(S::ObjectMonster *info, bool update = false);
        void ProcessBuffs();

        void Process() override;

        bool SetAction();

        void SetCurrentEffects();


    private:
        void ProcessFrames();

    public:
        int UpdateFrame();

        Missile *CreateProjectile(int baseIndex, MLibrary *library, bool blend, int count, int interval, int skip, int lightDistance = 6, bool direction16 = true, std::optional<Color*> &lightColour = std::nullopt, unsigned int targetID = 0) override;

    private:
        void PlaySummonSound();
        void PlayWalkSound(bool left = true);
    public:
        void PlayAppearSound();
        void PlayPopupSound();

        void PlayRunSound();

        void PlayJumpSound();

        void PlayFlinchSound();
        void PlayStruckSound();
        void PlayAttackSound();

        void PlaySecondAttackSound();

        void PlayThirdAttackSound();

        void PlayFourthAttackSound();
        void PlaySwingSound();
        void PlayDieSound();
        void PlayDeadSound();
        void PlayReviveSound();
        void PlayRangeSound();
        void PlaySecondRangeSound();

        void PlayThirdRangeSound();

        void PlayPickupSound();

        void PlayPetSound();
        void Draw() override;


        bool MouseOver(Point *p) override;

        void DrawBehindEffects(bool effectsEnabled) override;

        void DrawEffects(bool effectsEnabled) override;

        void DrawName() override;

        void CreateMonsterLabel(const std::string &word, int wordOrder);

        void DrawChat() override;
    };
}
